from rest_framework.viewsets import ViewSet, GenericViewSet
from utils.my_drf.viewsets import CustomModelViewSet
from django.utils import timezone
import base64
from utils.password_hashlib import pwd_sha256
from rest_framework.exceptions import APIException
from utils.my_drf.response import APIResponse
from . import models, serializer
from record.models import AdminRecord
from utils.captcha import validate_captcha
from utils.my_drf.admin_auth import set_admin_user_cache
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
from utils.my_drf.admin_auth import AdminJwtAuth, AdminPermission
from django.core.cache import cache
from utils.my_drf.pagination import CommonPageNumberPagination
from rest_framework.filters import SearchFilter
from django_filters.rest_framework import DjangoFilterBackend


# 查询账号
class UserQueryView(ViewSet):
    def create(self, request):
        username = request.data.get('username')
        try:
            # 账号存在且唯一
            models.Admins.objects.get(username=username)
        except Exception as e:
            return APIResponse(code=1101, msg='账号不存在！')

        return APIResponse(msg='账号存在！')


# 登录
class LoginView(ViewSet):
    def create(self, request):
        captcha_id = request.data.get('captcha_id')
        captcha = request.data.get('captcha')
        username = request.data.get('username')
        password = request.data.get('password')
        # 验证验证码
        validate_captcha(captcha_id, captcha)
        # 验证账号密码
        admin = self._verification_admin(username, password)
        # 存缓存
        set_admin_user_cache(admin)
        # 获取token
        token = self._get_token(admin)
        # 写记录
        ip_addr = request.META.get('REMOTE_ADDR')
        AdminRecord.objects.create(group=1, detail='登录系统，IP：{}'.format(ip_addr), admin=admin)
        return APIResponse(data={'username': admin.username, 'token': token})

    def _verification_admin(self, username, password):
        username = base64.b64decode(username).decode()
        try:
            admin = models.Admins.objects.get(username=username)
        except:
            raise APIException('账号或密码错误！')
        if not admin.is_active:
            raise APIException('该账号异常！')
        if timezone.now() < admin.date_lock:
            raise APIException('账号已被锁定，请于{}之后再尝试登录！'.format(admin.date_lock))
        pwd = pwd_sha256(password)
        if pwd != admin.password:
            admin.err_num += 1
            if admin.err_num >= 7:
                lock_time = 5 * (2 ** (admin.err_num - 7))
                admin.date_lock = timezone.now() + timezone.timedelta(minutes=lock_time)
                admin.save()
                raise APIException('密码错误次数过多，账号已被锁定！')
            admin.save()
            raise APIException('账号或密码错误！')
        if admin.err_num != 0:
            admin.err_num = 0
            admin.save()
        return admin

    def _get_token(self, user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token


# 修改密码
class AdminUpdatePassword(GenericViewSet):
    authentication_classes = [AdminJwtAuth, ]

    def create(self, request):
        old_password = request.data.get('oldPassword')
        new_password = request.data.get('newPassword')
        admin_user = request.user
        obj = models.Admins.objects.filter(pk=admin_user['id']).first()
        old_pwd = pwd_sha256(old_password)
        if old_pwd != obj.password:
            return APIResponse(code=1105, msg='旧密码不正确!')
        new_pwd = pwd_sha256(new_password)
        obj.password = new_pwd
        obj.save()
        AdminRecord.objects.create(group=1, detail='管理员修改了密码',
                                   admin_id=request.user.get('id'))
        return APIResponse(code=202)


# 管理员接口
class AdminsView(CustomModelViewSet):
    authentication_classes = [AdminJwtAuth, ]
    permission_classes = [AdminPermission, ]
    filter_backends = [SearchFilter, DjangoFilterBackend]
    search_fields = ['username', 'name']
    filterset_fields = ['department']
    queryset = models.Admins.objects.filter(is_delete=False).order_by('-id')
    serializer_class = serializer.AdminsSerializer
    pagination_class = CommonPageNumberPagination

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return serializer.GetAdminsSerializer
        return self.serializer_class

    def create(self, request, *args, **kwargs):
        res = super().create(request, *args, **kwargs)
        AdminRecord.objects.create(group=1, detail='添加管理员，内容：{}'.format(str(res.data.get('data'))),
                                   admin_id=request.user.get('id'))
        return res

    def update(self, request, *args, **kwargs):
        res = super().update(request, *args, **kwargs)
        AdminRecord.objects.create(group=1, detail='修改管理员，内容：{}'.format(str(res.data.get('data'))),
                                   admin_id=request.user.get('id'))
        cache.delete('admin_{}'.format(self.get_object().id))
        return res

    def destroy(self, request, *args, **kwargs):
        res = super().destroy(request, *args, **kwargs)
        AdminRecord.objects.create(group=1, detail='删除管理员，id：{}'.format(str(res.data.get('data'))),
                                   admin_id=request.user.get('id'))
        cache.delete('admin_{}'.format(res.data.get('data')))
        return res
